package org.robot.scm.platform.wxrobot;

import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.aigc.generation.models.QwenParam;
import com.alibaba.dashscope.utils.Constants;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.robot.scm.pojos.config.BaseConfig;
import org.robot.scm.platform.AbstractMonitor;
import org.robot.scm.platform.wxrobot.socket.SocketConnector;
import org.robot.scm.pojos.config.base.BasePlatform;
import org.robot.scm.pojos.enums.PlatformEnum;
import org.robot.scm.pojos.platform.RobotBaseNotify;
import org.robot.scm.utils.RequestHelper;
import org.robot.scm.utils.SendNoticeHelper;
import org.robot.scm.utils.StreamUtils;

/**
 * @Author : Awn create on 2024/4/26 11:37
 */
@Slf4j
public class RobotSocketConnector extends AbstractConnector {

    static {
        Constants.apiKey = "sk-776a56ccc4f446fa94875b80467b0826";
    }

    @Override
    public void run() {
        if (!AbstractMonitor.mainConfig.getEnables().contains(PlatformEnum.ROBOT.getVal())) {
            return;
        }
        try {
            BaseConfig config = getRobotConfig();
            String result = RequestHelper.get(String.format("http://%s/ext/www/key.ini", getHost(config.robotUrl())));
            JSONObject json = JSONObject.parseObject(result);
            String key = json.getString("key");
            String ws = String.format(config.getCurrentPlatform().getNoticeSrc(), key);
            new SocketConnector(ws, PlatformEnum.ROBOT.getVal(), (content) -> messageRecv(config, content)).connect();
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
    }

    public static void messageRecv(BaseConfig config, String content) {
        JSONObject jsonObject = JSON.parseObject(content);
        JSONObject msgObject = jsonObject.getJSONObject("data");
        if (Objects.isNull(msgObject)) {
            return;
        }
        String toId = msgObject.getString("toid");
        String fromId = msgObject.getString("fromid");
        String des = msgObject.getString("des");
        String messageId = msgObject.getString("id");
        String message = msgObject.getString("msg");

        // 当前消息不是给我（机器人）的忽略
        if (!StringUtils.equals(config.getCurrentPlatform().getWechatId(), toId)) {
            return;
        }

        // 非@我的和非配置无需@的一些信息忽略
        if (!des.contains("在群聊中@了你") && !des.contains("@Scm") && !getNotAtMeWords(config).contains(message)) {
            return;
        }

        String msg = StringUtils.deleteWhitespace(message).replaceAll("@Scm", "");

        // 机器人策略额外处理, true被处理了， false继续执行机器人操作， 这里是为了其他程序使用微信机器人做的额外处理
        if (AbstractRobotProcessor.doNext(config, fromId, msg)) {
            return;
        }

        // 无符合条件的策略还是执行机器人问答
        RobotBaseNotify notice = RobotBaseNotify.builder()
                .messageId(messageId)
                .toUserId(fromId)
                .content(callWithMessage(msg))
                .build();

        // 当前平台每个渠道需要发送的设备用户
        SendNoticeHelper.sendNotice(config, notice, PlatformEnum.ROBOT, fromId);
    }

    private static List<String> getNotAtMeWords(BaseConfig config) {
        List<BasePlatform> needAtMePlatforms = StreamUtils.filter(config.get().getPlatforms(), e -> Objects.nonNull(e.getNeedAtMe()) && !e.getNeedAtMe());
        return StreamUtils.flatConvert(needAtMePlatforms, BasePlatform::getKeywords);
    }

    private static BaseConfig getRobotConfig() {
        BasePlatform currentPlatform = AbstractMonitor.mainConfig.getPlatform(PlatformEnum.ROBOT);
        return new BaseConfig(AbstractMonitor.mainConfig, currentPlatform);
    }

    private static String getHost(String url) {
        // 正则表达式匹配协议头后面的部分，直到遇到下一个斜杠或结束
        Pattern pattern = Pattern.compile("(https?://)?[^/]+");
        Matcher matcher = pattern.matcher(url);
        if (matcher.find()) {
            // 如果匹配到了http(s)://，则去掉这一部分得到纯净的hostname
            if (matcher.group().startsWith("http://")) {
                return matcher.group().substring(7);
            } else if (matcher.group().startsWith("https://")) {
                return matcher.group().substring(8);
            }
        }
        return "";
    }

    /**
     * 千问模型
     */
    public static String callWithMessage(String question) {
        if (StringUtils.isBlank(question)) {
            return "我在呢, 想问点什么呢?";
        }
        try {
            QwenParam params = QwenParam.builder()
                    .model("qwen1.5-1.8b-chat")
                    .prompt(question)
                    .resultFormat(GenerationParam.ResultFormat.MESSAGE)
                    .build();
            GenerationResult result = new Generation().call(params);
            return result.getOutput().getChoices().get(0).getMessage().getContent();
        } catch (Exception e) {
            return "我没明白你的意思, 换个说法吧";
        }
    }
}
